import datetime
import time
from urllib.parse import urlparse

import jwt
import requests
from flask import current_app as app
from flask import make_response, redirect, request, session, url_for
from flask_restful import Resource


class Auth(Resource):

    def get(self):
        session['referer'] = request.args.get(
            'redirect') or request.referrer or request.host_url
        redirect_uri = request.host_url[:-1] + \
            app.config['DOCKER_PATH'] + url_for('api.authorized')
        auth_url = ("https://git.forchange.cn/oauth/authorize?client_id={app_id}&"
                    "redirect_uri={redirect_uri}&response_type=code&state=hardtoguess")
        return redirect(auth_url.format(app_id=app.config['APP_ID'], redirect_uri=redirect_uri))


class Authorized(Resource):

    def get(self):
        code = request.args.get('code')
        par = {
            'client_id': app.config['APP_ID'],
            'client_secret': app.config['APP_SECRET'],
            'code': code,
            'grant_type': 'authorization_code',
            'redirect_uri': request.host_url[:-1] + app.config['DOCKER_PATH'] + url_for('api.authorized')
        }
        r = requests.post('https://git.forchange.cn/oauth/token', params=par)
        resp = r.json()
        user = requests.get('https://git.forchange.cn/api/v4/user', params={
            'access_token': resp['access_token']
        })
        user_info = user.json()
        user_jwt = {
            'id': user_info['id'],
            'name': user_info['name'],
            'username': user_info['username'],
            'avatar': user_info['avatar_url'],
            'exp': int(time.time() + 36000)
        }
        token = jwt.encode(
            user_jwt, app.config['JWT_SECRET'], algorithm='HS256')
        token = str(token, encoding='utf8')
        t = datetime.datetime.utcnow() + datetime.timedelta(hours=10)
        gmt = t.strftime(app.config['GMT_FORMAT'])
        referer = session['referer']
        parsed_result = urlparse(referer)
        response = make_response('', 302, {
            'Location': referer if referer else app.config['DOCKER_PATH'] + url_for('main.index'),
            'Set-Cookie': 'token={}; Domain={}; Path={}; Expires={}'.format(token, parsed_result.hostname,
                                                                            parsed_result.path,
                                                                            gmt)
        })
        if user_info.get('is_admin'):
            return response

        # 验证用户为 某一个project 的组成员
        for project in app.config['PROJECTS']:
            members = 1
            page = 1
            while members:
                group_members = requests.get(
                    'https://git.forchange.cn/api/v4/projects/{project}/members/all'.format(
                        project=project.replace('/', '%2F')
                    ),
                    params={
                        'page': page,
                        'per_page': 100,
                        'access_token': resp['access_token']
                    })
                members = group_members.json()
                if isinstance(members, list):
                    for user in members:
                        if user['username'] == user_info['username'] and user['state'] == 'active':
                            return response
                page += 1

        return {'msg': 'Access denied'}, 403
